package com.wlf.server.web.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wlf.server.common.context.BeanContext;
import com.wlf.server.common.em.Const;
import com.wlf.server.common.entity.ScheduleJob;
import com.wlf.server.common.entity.ScheduleLog;
import com.wlf.server.common.entity.SysCron;
import com.wlf.server.common.quartz.QuartzService;
import com.wlf.server.common.service.ScheduleJobService;
import com.wlf.server.common.service.ScheduleLogService;
import com.wlf.server.common.service.SysCronService;
import com.wlf.server.web.dto.ParamPage;
import com.wlf.server.web.util.AjaxBean;
import org.quartz.Scheduler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDateTime;

@RestController
@RequestMapping("/task")
public class ScheduleController {
    @Resource
    ScheduleJobService jobService;
    @Resource
    ScheduleLogService logService;
    @Resource
    private Scheduler scheduler;
    @Resource
    private BeanContext beanContext;
    @Resource
    private SysCronService cronService;
    /**
     * 获取任务列表
     * @param job 查询参数
     * @param paramPage 分页
     * @return 任务列表
     */
    @GetMapping("/list")
    AjaxBean list(ScheduleJob job, ParamPage paramPage) {
        LambdaQueryWrapper<ScheduleJob> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(job.getName())){
            wrapper.like(ScheduleJob::getName,job.getName());
        }
        Page<ScheduleJob> page = jobService.page(new Page<>(paramPage.getCurrent(), paramPage.getSize()),wrapper);
        return AjaxBean.getOkPage(page);
    }

    /**
     * 初始化表单输入建议
     * @return 返回建议
     */
    @GetMapping("/init-form")
    AjaxBean initForm(){
        Dict dict = Dict.create();
        dict.set("beanNameList",beanContext.getBeanNameList(Const.TaskBeanKey).
                stream().map(i -> Dict.create().set("value",i)).toList());

        dict.set("cronList",cronService.list().
                stream().map(i -> Dict.create()
                        .set("value",i.getExpression())
                        .set("desc",i.getDesc())).toList());
        return AjaxBean.getOkData(dict);
    }

    /**
     * 根据任务ID获取任务信息
     * @param id 任务ID
     * @return 任务信息
     */
    @GetMapping("/get")
    AjaxBean get(String id){
        return AjaxBean.getOkData(jobService.getById(id));
    }

    /**
     * 更新或者删除
     * @param job 任务
     * @return 操作结果
     */
    @PostMapping("/save-or-update")
    AjaxBean saveOrUpdate(ScheduleJob job){
        if (StrUtil.isBlank(job.getId())){
            job.setId(IdWorker.getIdStr());
            job.setCreateTime(LocalDateTime.now());
            QuartzService.createJob(scheduler,job);
        } else {
            QuartzService.updateJob(scheduler,job);
        }
        return AjaxBean.getByBool(jobService.saveOrUpdate(job));
    }

    /**
     * 开启或停止定时任务
     * @param job 实体
     * @return 操作结果
     */
    @PostMapping("/update-status")
    AjaxBean updateStatus(ScheduleJob job){
        String id = job.getId();
        if (job.getStatus() == 0){
            QuartzService.resumeJob(scheduler,Long.parseLong(id));
        } else {
            QuartzService.pauseJob(scheduler,Long.parseLong(id));
        }
        return AjaxBean.getByBool(jobService.updateById(job));
    }
    /**
     * 根据任务ID运行一个任务
     * @param id 任务ID
     * @return 运行状态
     */
    @GetMapping("/run")
    AjaxBean run(String id){
        ScheduleJob job = jobService.getById(id);
        QuartzService.run(scheduler,job);
        return AjaxBean.getOkMsg();
    }

    /**
     * 停止定时任务
     * @param jobId 任务Id
     * @return 执行结果
     */
    @GetMapping("/pause")
    AjaxBean pause(String jobId){
        ScheduleJob scheduleJob = jobService.getById(jobId);
        QuartzService.pauseJob(scheduler,Long.parseLong(jobId));
        scheduleJob.setStatus(1);
        return AjaxBean.getByBool(jobService.updateById(scheduleJob));
    }

    /**
     * 恢复定时任务
     * @param id 任务Id
     * @return 执行结果
     */
    @GetMapping("/resume")
    AjaxBean resume(String id){
        ScheduleJob scheduleJob = jobService.getById(id);
        QuartzService.resumeJob(scheduler,Long.parseLong(id));
        scheduleJob.setStatus(1);
        jobService.updateById(scheduleJob);
        return AjaxBean.getOkMsg();
    }


    /**
     * 删除一个任务
     * @param id 任务ID
     * @return 删除结果
     */
    @PostMapping("/del")
    AjaxBean del(String id){
        QuartzService.deleteJob(scheduler,Long.parseLong(id));
        jobService.removeById(id);
        return AjaxBean.getOkMsg();
    }

    final String CRON = "/cron";
    /**
     * cron维主数据
     * @param cron 查询参数
     * @param paramPage 分页
     * @return 结果
     */
    @GetMapping(CRON+"/list")
    AjaxBean cornList(SysCron cron,ParamPage paramPage){
        LambdaQueryWrapper<SysCron> wrapper = new LambdaQueryWrapper<>();
        // 待写查询参数
        if (StrUtil.isNotBlank(cron.getDesc())){
            wrapper.like(SysCron::getDesc,cron.getDesc());
        }
        wrapper.orderByDesc(SysCron::getId);
        return AjaxBean.getOkPage(
                cronService.page(Page.of(paramPage.getCurrent(),  paramPage.getSize()),wrapper)
        );
    }

    /**
     * 删除维护的Cron表达式
     * @param id id
     * @return 操作结果
     */
    @PostMapping(CRON+"/del")
    AjaxBean cronDel(String id){
        return AjaxBean.getByBool(cronService.removeById(id));
    }

    /**
     * 获取表达式
     * @param id id
     * @return 实体
     */
    @GetMapping(CRON+"/get")
    AjaxBean cronGet(String id){
        return AjaxBean.getOkData(cronService.getById(id));
    }

    /**
     * 更新或者新增Cron表达式
     * @param cron 实体
     * @return 操作结果
     */
    @PostMapping(CRON+"/save-or-update")
    AjaxBean cronSaveOrUpdate(SysCron cron){
        return AjaxBean.getByBool(cronService.saveOrUpdate(cron));
    }

    final String LOG = "/log";
    /**
     * 获取任务日子列表
     * @param log 查询参数
     * @param paramPage 分页
     * @return 日志列表
     */
    @GetMapping(LOG+"/list")
    AjaxBean logList(ScheduleLog log, ParamPage paramPage) {
        LambdaQueryWrapper<ScheduleLog> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(log.getJobId())){
            wrapper.eq(ScheduleLog::getJobId,log.getJobId());
        }
        if (ObjectUtil.isNotEmpty(log.getCreateTimeList())){
            wrapper.between(ScheduleLog::getCreateTime,
                    DateUtil.parse(log.getCreateTimeList().get(0)+" 00:00:00"),
                    DateUtil.parse(log.getCreateTimeList().get(1)+" 23:59:59")
                    );
        }
        wrapper.orderByDesc(ScheduleLog::getId);
        Page<ScheduleLog> page = logService.page(new Page<>(paramPage.getCurrent(), paramPage.getSize()),wrapper);
        for (ScheduleLog record : page.getRecords()) {
            record.setJobName(jobService.getById(record.getJobId()).getName());
        }
        return AjaxBean.getOkPage(page);
    }

    /**
     * 任务列表
     */
    @GetMapping(LOG+"/jobList")
    AjaxBean logJobList(){
        return AjaxBean.getOkData(jobService.list());
    }


    /**
     * 删除类别
     */
    public enum DelType{
        /**
         * 删除全部
         */
        ALL,
        /**
         * 一个月前
         */
        YI,
        /**
         * 三个月前
         */
        SAN,
        /**
         * 六个月前
         */
        LIU,
        /**
         * 一年前
         */
        YEAR
    }
    /**
     * 删除任务执行日志
     */
    @PostMapping(LOG+"/del")
    AjaxBean logDel(DelType type){
        return logService.del(type);
    }

}
